﻿using System.Windows.Controls;
using System.Collections.Generic;
using TinyEngine.Core.Services;
using System.Windows;
using TinyEngine.Core;
using TinyEngineEditor.EntityEditors;

namespace TinyEngineEditor.Explorer
{
    public partial class ProjectExplorer : UserControl
    {
        Dictionary<string, TreeViewItem> TreeNodes = new Dictionary<string, TreeViewItem>();
        public ProjectExplorer()
        {
            InitializeComponent();
            treeView1.PreviewMouseRightButtonDown += new System.Windows.Input.MouseButtonEventHandler(treeView1_PreviewMouseRightButtonDown);
            
            Setup();
            Session.AssetsChanged += new System.Action(Session_AssetsChanged);
        }

        void Session_AssetsChanged()
        {
            LoadAssets(TreeNodes["Assets"]);
        }

        void treeView1_PreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            TreeView tv = (TreeView)sender;
            IInputElement element = tv.InputHitTest(e.GetPosition(tv));
            while (!((element is TreeView) || element == null))
            {
                if (element is TreeViewItem)
                    break;

                if (element is FrameworkElement)
                {
                    FrameworkElement fe = (FrameworkElement)element;
                    element = (IInputElement)(fe.Parent ?? fe.TemplatedParent);
                }
                else
                    break;
            }
            if (element is TreeViewItem)
            {

                TreeViewItem itm = element as TreeViewItem;
                ContextMenu mnu = null;
                if (itm.Header == "Assets")
                {
                    mnu = Resources["AssetsContextMenu"] as ContextMenu;
                }
                else
                {
                    mnu = Resources["SceneGraphContextMenu"] as ContextMenu;
                }
                
                treeView1.ContextMenu = mnu;

                element.Focus();
                e.Handled = true;
            }
            
        }

        void Setup()
        {
            Session.SceneLoaded += new System.Action<string>(Session_SceneLoaded);

            AddDefaultRootNodes();
        }
        private void AddDefaultRootNodes()
        {
            TreeNodes.Clear();
            treeView1.Items.Clear();
            var node = new TreeViewItem();
            node.Header = "Scene Graph";
            TreeNodes.Add(node.Header.ToString(), node);

            node = new TreeViewItem();
            node.Header = "Templates";
            TreeNodes.Add(node.Header.ToString(), node);

            node = new TreeViewItem();
            node.Header = "Cameras";
            TreeNodes.Add(node.Header.ToString(), node);

            node = new TreeViewItem();
            node.Header = "Assets";
            TreeNodes.Add(node.Header.ToString(), node);

            node = new TreeViewItem();
            node.Header = "Textures";
            TreeNodes.Add(node.Header.ToString(), node);
            TreeNodes["Assets"].Items.Add(node);

            node = new TreeViewItem();
            node.Header = "Fonts";
            TreeNodes.Add(node.Header.ToString(), node);
            TreeNodes["Assets"].Items.Add(node);

            treeView1.Items.Add(TreeNodes["Scene Graph"]);
            treeView1.Items.Add(TreeNodes["Templates"]);
            treeView1.Items.Add(TreeNodes["Cameras"]);
            treeView1.Items.Add(TreeNodes["Assets"]);
        }

        void Session_SceneLoaded(string path)
        {
            AddDefaultRootNodes();

            SetupContextMenus();
            LoadSceneGraph(TreeNodes["Scene Graph"]);
            LoadAssets(TreeNodes["Assets"]);
        }

        private void SetupContextMenus()
        {
            var asm = ServiceManager.GetService<AssemblyService>();
            var mnu = Resources["SceneGraphContextMenu"] as ContextMenu;
            var addNode = new MenuItem()
            {
                Header = "Add Entity"
            };
            mnu.Items.Add(addNode);
            foreach (var item in asm.EntityTypes)
            {
                var newEntity = new MenuItem()
                {
                    Header = item.Name,
                    Tag = item
                };
                newEntity.Click += new RoutedEventHandler(newEntity_Click);
                addNode.Items.Add(newEntity);
            }
        }

        void newEntity_Click(object sender, RoutedEventArgs e)
        {
            var mnu = sender as MenuItem;
            MessageBox.Show(((System.Type)mnu.Tag).Name);
        }

        private void LoadAssets(TreeViewItem treeNode)
        {
            
            var node = TreeNodes["Textures"];
            node.Items.Clear();

            var assets = ServiceManager.GetService<AssetLibrary>();
            foreach (var item in assets.Sprites)
            {
                
                var nd = new TreeViewItem();
                nd.Header = item.Value.Name;
                nd.Tag = item;
                node.Items.Add(nd);
            }
        }

        private void LoadSceneGraph(TreeViewItem itm)
        {
            var scene = Session.SceneManager.ActiveGameScene;
            foreach (var item in  scene.Graph.Entities)
            {
                AddSceneItemRecursive(item, itm);
            }
        }

        private void AddSceneItemRecursive(TinyEngine.Core.IEntity item, TreeViewItem itm)
        {
            var node = new TreeViewItem();
            node.Header = item.Name;
            node.Tag = item;
            itm.Items.Add(node);

            foreach (var child in item.Children)
            {
                AddSceneItemRecursive(child, node);
            }
        }

        private void DoubleClickTree(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (treeView1.SelectedItem != null)
            {
                var node = treeView1.SelectedItem as TreeViewItem;
                if (node.Tag != null)
                {
                    if (node.Tag is IEntity)
                    {
                        EditorHelper.LoadEditor(node.Tag as IEntity);
                    }
                }
            }
        }
    }
}
